/**
 * @file:    ring_queue.c
 * @author:  Garry Meng
 * @date:    2025-08-04
 * @brief:   ring queue management
 *
 * Copyright (c) 2025, Garry Meng, <menggaoling@163.com>
 *
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *
**/

#include "ring_queue.h"

#define QUEUE_SIZE 20/*队列中元素最大数量QUEUE_SIZE = BUFF SIZE - 1*/
#define ARRAY_SIZE (QUEUE_SIZE+1)

uint16 queue_count; /*队列中元素个数*/

void ringQueueInit(QUEUE_TYPE* queue, uint8* data,uint16 queue_size)
{
    queue->front = 1;
    queue->rear = 0;
    queue->queue_size = queue_size;
    queue->data = data;
	queue_count = 0;
}

/*insert*/
bool enQueue(QUEUE_TYPE* queue, uint8 value)
{
    if (isQueueFull(queue))
    { 
        return false;
    }        
    queue->rear = (queue->rear + 1) % (queue->queue_size + 1);
    queue->data[queue->rear] = value;
	queue_count++;

    return true;
}

bool deQueue(QUEUE_TYPE* queue )
{
    if (isQueueEmpty(queue))
    {
        return false;
    }
    queue->front = (queue->front + 1) % (queue->queue_size + 1);
    queue_count--;
    return true;
}

uint8 getQueueFirst(QUEUE_TYPE* queue )
{
    return queue->data[queue->front];
}

bool isQueueEmpty(QUEUE_TYPE* queue )
{
    return (queue->rear + 1) % (queue->queue_size + 1) == queue->front;
}

bool isQueueFull(QUEUE_TYPE* queue )
{
    return (queue->rear + 2) % (queue->queue_size + 1) == queue->front;
}

uint16 getQueueLength(QUEUE_TYPE* queue)
{
    if (isQueueFull(queue))
    {
        return queue->queue_size;
    }
    else if (isQueueEmpty(queue))
    {
        return 0;
    }
    else
    {
        return (queue->rear + (queue->queue_size - queue->front) + 1 + (queue->front > queue->rear)) % queue->queue_size;
    }    
}

uint16 getQueueRemainSize(QUEUE_TYPE* queue )
{
    return (queue->queue_size - getQueueLength(queue));
}